using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Machine.Specifications;
using Machine.Specifications.Model;

namespace Avinor.NET.Specs
{
    [Subject(typeof(Flight))]
    public class when_served_a_stream :
        parser_context
    {
        static List<Flight> flights;

        Establish context = () =>
        {
            CreateParser(@"SampleFiles\25Flights.xml");
        };

        Because of = () =>
        {
            flights = parser.GetFlights().ToList();
        };

        It should_find_flights = () =>
        {
            flights.Count().ShouldBeGreaterThan(0);
        };
    }

    [Subject(typeof(Flight))]
    public class when_reading_a_known_sample_xml_stream_with_25_flights :
        parser_context
    {
        static List<Flight> flights;
        Establish context = () =>
        {
            CreateParser(@"SampleFiles\25Flights.xml");
        };    
        Because of = () =>
        {
            flights = parser.GetFlights().ToList();
        };

        It should_find_25_flights = () =>
        {
            flights.Count.ShouldEqual(25);
        };
    }

    [Subject(typeof(Flight))]
    public class when_reading_a_sample_flight_from_the_sample_file
        : parser_context
    {
        static Flight flight;
        Establish context = () =>
        {
            CreateParser(@"SampleFiles\SingleFlight.xml");
        };   
        Because of = () =>
        {
            flight = parser.GetFlights().First();
        };
        It should_be_from_airline_AUL = () =>
        {
            flight.Airline.ShouldEqual("AUL");
        };

        It should_have_flight_number_AUL9333 = () =>
        {
            flight.FlightId.ShouldEqual("AUL9333");
        };
        It should_have_a_scheduled_time_of_2009_07_05_1000 = () =>
        {
            flight.ScheduledTime.ShouldEqual(new DateTime(2009, 07, 05, 10, 00, 00));
        };
        It should_come_from_TMP_airport = () =>
        {
            flight.Airport.ShouldBeEqualIgnoringCase("TMP");
        };
    }

    [Subject(typeof(Flight))]
    public class when_reading_a_flight_connecting_with_Schengen_from_the_sample_file
    : parser_context
    {
        static Flight flight;
        Establish context = () =>
        {
            CreateParser(@"SampleFiles\SchengenFlight.xml");
        };  
        Because of = () =>
        {
            flight = parser.GetFlights().First();
        };
        It should_connect_with_Schengen = () =>
        {
            flight.LastLeg.ShouldEqual(FlightArea.Schengen);
        };
    }

    [Subject(typeof(Flight))]
    public class when_reading_a_flight_connecting_with_Domestic_from_the_sample_file
    : parser_context
    {
        private static Flight flight;
        Establish context = () =>
        {
            CreateParser(@"SampleFiles\DomesticFlight.xml");
        };
        Because of = () =>
        {
            flight = parser.GetFlights().First();
        };
        It should_connect_with_Domestic = () =>
        {
            flight.LastLeg.ShouldEqual(FlightArea.Domestic);
        };
    }

    [Subject(typeof(Flight))]
    public class when_reading_a_flight_connecting_with_International_from_the_sample_file
    : parser_context
    {
        private static Flight flight;
        Establish context = () =>
        {
            CreateParser(@"SampleFiles\InternationalFlight.xml");
        };
        Because of = () =>
        {
            flight = parser.GetFlights().First();
        };
        It should_connect_with_International = () =>
        {
            flight.LastLeg.ShouldEqual(FlightArea.International);
        };
    }

    [Subject(typeof(Flight))]
    public class when_reading_an_arriving_flight_from_the_sample_file
    : parser_context
    {
        private static Flight flight;
        Establish context = () =>
        {
            CreateParser(@"SampleFiles\ArrivingFlight.xml");
        };
        Because of = () =>
        {
            flight = parser.GetFlights().First();
        };
        It should_be_an_arriving_flight = () =>
        {
            flight.Direction.ShouldEqual(FlightDirection.Arrival);
        };
        It should_use_belt_2 = () =>
        {
            flight.Belt.ShouldEqual(2);
        };
        It should_not_have_a_gate = () =>
        {
            flight.Gate.ShouldBeNull();
        };
    }

    [Subject(typeof(Flight))]
    public class when_reading_a_departing_flight_from_sample_file
        : parser_context
    {
        private static Flight flight;
        Establish context = () =>
        {
            CreateParser(@"SampleFiles\DepartingFlight.xml");
        };        
        Because of = () =>
        {
            flight = parser.GetFlights().First();
        };
        It should_be_a_departing_flight = () =>
        {
            flight.Direction.ShouldEqual(FlightDirection.Departure);
        };
        It should_not_have_a_belt = () =>
        {
            flight.Belt.ShouldBeNull();
        };
        It should_depart_from_gate_12 = () =>
        {
            flight.Gate.ShouldEqual("12");
        };
    }

    public class parser_context
    {
        protected static AvinorFlightParser parser;
        
        protected static void CreateParser(string fileName)
        {
            _sampleStream = new FileStream(fileName,FileMode.Open);
            parser = new AvinorFlightParser(_sampleStream);
        }
        
        Cleanup after_all = () =>
        {
            _sampleStream.Close();
        };

        static FileStream _sampleStream;
    }
}
